package analysis

import (
	"codejy/globalfunc"
	"codejy/store"
	"codejy/structdef"
	"codejy/utils"
	"strings"
)

func init() {

	globalfunc.RegisterFuncAll("IsInt", IsInt)
	globalfunc.RegisterFuncAll("IsNumber", IsNumber)
	globalfunc.RegisterFuncAll("IsFloat", IsFloat)
	globalfunc.RegisterFuncAll("IsBool", IsBool)

	globalfunc.RegisterFuncAll("IsIncrementDecrement", IsIncrementDecrement)

	globalfunc.RegisterFuncAll("AssignmentStatement", AssignmentStatement)
	globalfunc.RegisterFuncAll("IsVariableNameLegal", IsVariableNameLegal)
	globalfunc.RegisterFuncAll("IsVariableDefine", IsVariableDefine)
	globalfunc.RegisterFuncAll("IsFuncNameParameter", IsFuncNameParameter)
	globalfunc.RegisterFuncAll("IsAnnotation", IsAnnotation)
	globalfunc.RegisterFuncAll("IsInstanceAddress", IsInstanceAddress)
	globalfunc.RegisterFuncAll("IsVariableNameStr", IsVariableNameStr)
	globalfunc.RegisterFuncAll("IsCalculateFunctionCall", IsCalculateFunctionCall)
	globalfunc.RegisterFuncAll("IsMethodCall", IsMethodCall)

}

// 变量能使用的字符
var VariableNameCharacter = []rune("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")

// 数字范围
var NumberRunes = []rune("0123456789")

// 判断变量命名是否合法
func IsVariableNameLegal(name string) {
	if len(name) == 0 {
		panic("变量名称没有")
	}
	//关键字验证
	b := store.IsKeyword(name)
	if !b {
		panic(name + "是关键字不能作为,变量名|函数名|类型名|属性名")
	}
	//判断是否符合字母数字下划线命名
	for _, r := range []rune(name) {
		if !IsVariableNameCharacter(r) {
			panic(name + "变量名|函数名|类型名|属性名定义不合法,只支持数字字母下划线")
		}
	}
}

// 判断是否是变量字符
func IsVariableNameCharacter(r rune) bool {
	for _, v := range VariableNameCharacter {
		if v == r {
			return true
		}
	}
	return false
}
func IsVariableNameStr(str string) bool {
	runes := []rune(str)
	for _, v := range VariableNameCharacter {
		for i := range runes {
			if runes[i] == v {
				return true
			}
		}
	}
	return false
}

// 判断是否是变量var 定义
func IsVariableDefine(codeLine string) bool {
	//判断开头是否是var
	if strings.Index(codeLine, "var") != 0 {
		return false
	}

	return true
}

// 判断是否是赋值表达式,规则: 开头是字母数字下划线
func AssignmentStatement(threadStore *structdef.ThreadStore, line string) bool {
	//获取第一个=号
	index := strings.Index(line, "=")
	if index == -1 {
		return false
	}
	//截取=之间的字符串
	varName := line[:index]
	//获取变量在内存中是否存在
	_, _, p := store.Get3LevelVariable(threadStore, varName)
	if p {
		return true
	}
	return false
}

// 判断是函数定义
func IsFunctionDefine(codeLine string) bool {
	//判断开头是func
	index := strings.Index(codeLine, "func")
	if index != 0 {
		return false
	}
	//判断结尾是{
	index1 := strings.Index(codeLine, "{")
	if index1 != len(codeLine)-1 {
		return false
	}
	//截取func和{之间的字符串，判断长度是否大于0
	if len(codeLine[index+4:index1]) == 0 {
		return false
	}
	return true
}

// 判断是类型定义
func IsTypeDefine(codeLine string) bool {
	//判断开头是type
	if strings.Index(codeLine, "type") != 0 {
		return false
	}
	//判断结尾是{
	index := strings.Index(codeLine, "{")
	if strings.Index(codeLine, "{") != len(codeLine)-1 {
		return false
	}
	//截取type和{之间的字符串，判断长度是否大于0
	if len(codeLine[4:index]) == 0 {
		return false
	}
	return true
}

// 判断是类型函数定义
func IsTypeFunctionDefine(codeLine string) bool {
	//判断开头是func
	if strings.Index(codeLine, "def") != 0 {
		return false
	}
	//判断结尾是{
	index := strings.Index(codeLine, "{")
	if index != len(codeLine)-1 {
		return false
	}
	//截取def和{之间的字符串，判断长度是否大于0
	if len(codeLine[3:index]) == 0 {
		return false
	}
	return true
}

// 判断是否是匿名函数
func IsAnonymousFunctionDefine(codeLine string) bool {
	//判断是func
	start := strings.Index(codeLine, "func")
	if strings.Index(codeLine, "func") == -1 {
		return false
	}
	//判断结尾是{
	index := strings.Index(codeLine, "{")
	if index != len(codeLine)-1 {
		return false
	}
	//截取func和{之间的字符串，判断长度是否不是0
	if len(codeLine[start+4:index]) != 0 {
		return false
	}
	return true
}

// 判断是否是defer语句
func IsDefer(codeLine string) bool {
	if codeLine == "defer{" {
		return true
	}
	return false
}

// 判断是否是continue语句
func IsContinue(codeLine string) bool {
	if codeLine == "continue" {
		return true
	}
	return false
}

// 判断是否是break语句
func IsBreak(codeLine string) bool {
	if codeLine == "break" {
		return true
	}
	return false
}

// 判断是否是结束程序语句
func IsExit(codeLine string) bool {
	if strings.HasPrefix(codeLine, "exit") {
		return true
	}
	//判断(和)是否成对出现
	count := strings.Count(codeLine, "(")
	if count > 0 && count != strings.Count(codeLine, ")") {
		return false
	}
	return false
}

// 判断是否是Throw语句
func IsThrow(codeLine string) bool {
	if strings.HasPrefix(codeLine, "throw") {
		return true
	}
	//判断(和)是否成对出现
	count := strings.Count(codeLine, "(")
	if count > 0 && count != strings.Count(codeLine, ")") {
		return false
	}
	return false
}

// 判断是否是receive语句
func IsReceive(codeLine string) bool {
	if strings.HasPrefix(codeLine, "receive") {
		return true
	}
	//判断(和)是否成对出现
	count := strings.Count(codeLine, "(")
	if count > 0 && count != strings.Count(codeLine, ")") {
		return false
	}
	return false
}

// 判断是否是自增自减语句
func IsIncrementDecrement(codeLine string) bool {
	//判断结尾是否是自增自减,不用正则表达式
	if strings.HasSuffix(codeLine, "++") || strings.HasSuffix(codeLine, "--") {
		return true
	}
	return false
}

// 判断是多行字符串
func IsMultiLineString(codeLine string) bool {
	if strings.HasSuffix(codeLine, "\"\"\"") {
		return true
	}
	return false
}

// 判断是否是实例化语句
func IsNewInstance(codeLine string) bool {
	//1.判断开头是否是new
	if !strings.HasPrefix(codeLine, "new(") {
		return false
	}
	//2.判断结尾是否是)
	if !strings.HasSuffix(codeLine, ")") {
		return false
	}
	//3.判断括号是否成对出现
	count := strings.Count(codeLine, "(")
	if count > 0 && count != strings.Count(codeLine, ")") {
		return false
	}
	return true
}

// 判断是否是核心库函数
func IsCoreLibFunCall(codeLine string) bool {
	if strings.HasPrefix(codeLine, "core&") {
		return true
	}
	return false
}

// 判断是否是函数调用
func IsMethodCall(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断是否存在(
	//获取第一个(的位置
	index := strings.Index(codeLine, "(")
	if index == -1 {
		return false
	}
	//判断(和)是否成对出现
	count := strings.Count(codeLine, "(")
	if count > 0 && count != strings.Count(codeLine, ")") {
		return false
	}
	//截取到(之前的字符串
	funName := codeLine[:index]
	//获取自定义函数定义
	b := store.GetCurrentFunDefinition(threadStore, funName)
	if b != nil {
		return true
	}
	//获取系统函数定义
	b2 := globalfunc.ExecuteFunc("IsFunDefaultExist", funName).(bool)
	if b2 {
		return true
	}
	//获取函数名称在变量中是否存在
	variable, b3 := store.GetVariable(threadStore, funName)
	if b3 { //如果存在那么判断变量的类型是否是函数定义类型
		if variable.VarType == globalfunc.ExecuteFunc("GetFUNCDEF").(int) {
			return true
		}
	}

	return false
}

// 判断是否是多级函数调用()()
func IsMethodCallMulti(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断是否存在)(
	if !strings.Contains(codeLine, ")(") {
		return false
	}
	//获取第一个(的位置
	index := strings.Index(codeLine, "(")
	if index == -1 {
		return false
	}
	//判断(和)是否成对出现
	count1 := strings.Count(codeLine, "(")
	count2 := strings.Count(codeLine, ")")
	if count1 != count2 || count1 < 2 { //()()这种情况才是多级函数调用
		return false
	}

	//截取到(之前的字符串
	funName := codeLine[:index]
	//获取自定义函数定义
	b := store.GetCurrentFunDefinition(threadStore, funName)
	if b != nil {
		return true
	}
	//获取系统函数定义
	b2 := globalfunc.ExecuteFunc("IsFunDefaultExist", funName).(bool)
	if b2 {
		return true
	}
	//获取函数名称在变量中是否存在
	variable, b3 := store.GetVariable(threadStore, funName)
	if b3 { //如果存在那么判断变量的类型是否是函数定义类型
		if variable.VarType == globalfunc.ExecuteFunc("GetFUNCDEF").(int) {
			return true
		}
	}

	return false
}

// 判断是否是if语句
func IsIf(codeLine string) bool {
	//判断开头是否是if
	if !strings.HasPrefix(codeLine, "if") {
		return false
	}
	//判断结尾是否是{
	if !strings.HasSuffix(codeLine, "{") {
		return false
	}
	return true

}

// 判断是否是switch语句
func IsSwitch(codeLine string) bool {
	//判断开头是否是switch
	if !strings.HasPrefix(codeLine, "switch") {
		return false
	}
	//判断结尾是否是{
	if !strings.HasSuffix(codeLine, "{") {
		return false
	}
	return true
}

// 判断是否是for语句
func IsFor(codeLine string) bool {
	//判断开头是否是for
	if !strings.HasPrefix(codeLine, "for") {
		return false
	}
	//判断结尾是否是{
	if !strings.HasSuffix(codeLine, "{") {
		return false
	}
	return true
}

// 判断是否是to->语句(函数返回值)
func IsTo(codeLine string) bool {
	//判断开头是否是to->
	if !strings.HasPrefix(codeLine, "to") {
		return false
	}
	return true
}

// 判断是否是global.的方法调用
func IsGlobalMethodCall(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断开头是否是global.
	if !strings.HasPrefix(codeLine, "global.") {
		return false
	}
	//取消global.
	codeLine = codeLine[7:]
	//获取主文件的函数定义判断是否是函数调用
	call := IsMethodCall(threadStore, codeLine)
	if !call {
		return false
	}
	return true
}

// 判断是否是global.xx=xx的全局变量赋值
func IsGlobalPropAssignment(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断开头是否是global.
	if !strings.HasPrefix(codeLine, "global.") {
		return false
	}
	//获取=号的位置
	index := strings.Index(codeLine, "=")
	if index == -1 {
		return false
	}
	//截取=号前面的字符串
	varName := codeLine[7:index]
	//获取主文件的全局变量定义判断是否是全局变量赋值
	_, b := store.GetGlobalVariable(threadStore, varName)
	if !b {
		return false
	}
	return true
}

// 判断是否是global.的全局变量
func IsGlobalProp(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断是否存在global.
	if !strings.HasPrefix(codeLine, "global.") {
		return false
	}
	//截取=global.后面的字符串
	globalVariable := codeLine[7:]
	//获取主文件的全局变量定义判断是否是全局变量赋值
	_, b := store.GetGlobalVariable(threadStore, globalVariable)
	if !b {
		return false
	}
	return true
}

// 判断是实例地址调用属性
func IsInstanceAddressProp(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断开头是否是@#@
	if !strings.HasPrefix(codeLine, "@#@") {
		return false
	}
	//截取最后一个@#@的位置
	index := strings.LastIndex(codeLine, "@#@")
	//截取@#@前面面的字符串,包括@#@
	addr := codeLine[:index+3]
	//获取实例
	instance, b := store.GetInstanceProp(threadStore, addr)
	if !b {
		return false
	}
	//截取@#@后面的字符串,包括点
	prop := codeLine[index+4:]
	_, b = instance[prop]
	if !b {
		return false
	}
	return true
}

// 判断是实例地址调用方法
// @#@xxx@#@.show()
func IsInstanceAddressMethod(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断开头是否是@#@
	if !strings.HasPrefix(codeLine, "@#@") {
		return false
	}

	//截取最后一个@#@的位置
	index := strings.LastIndex(codeLine, "@#@")
	//截取@#@前面面的字符串,包括@#@
	addr := codeLine[:index+3]
	//获取实例
	instance, b := store.GetInstanceProp(threadStore, addr)
	if !b {
		return false
	}
	typeName, _ := instance["@TYPENAME@"]  //获取实例的类型名称
	scope, _ := instance["@TYPEFILEPATH@"] //获取实例的类型名称
	typeDefinition := store.GetTypeDefinition(scope.Value, typeName.Value)
	if typeDefinition == nil {
		return false
	}

	//截取@#@后面的字符串,包括点
	funName := codeLine[index+4:]
	//获取第一个(的位置
	index = strings.Index(funName, "(")
	if index == -1 {
		return false
	}
	//截取第一个(之前的字符串
	funName = funName[:index]
	//判断是否是实例函数调用
	_, b = typeDefinition.Methods[funName]
	if !b {
		return false
	}

	return true
}

// 判断是否开头是this.的方法调用
func IsThisMethodCall(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断开头是否是this.
	if !strings.HasPrefix(codeLine, "this.") {
		return false
	}
	//获取当前实例地址
	currentInstanceAddress := threadStore.CurrentInstanceAddress
	if currentInstanceAddress == "" {
		return false
	}
	//获取地址对应的实例 ,判断此实例是否有此属性
	prop, _ := store.GetInstanceProp(threadStore, currentInstanceAddress)
	//获取第一个点位置
	index := strings.Index(codeLine, ".")
	//截取第一个.之后的字符串
	funName := codeLine[index+1:]
	typeName, _ := prop["@TYPENAME@"]  //获取实例的类型名称
	scope, _ := prop["@TYPEFILEPATH@"] //获取实例的类型名称
	typeDefinition := store.GetTypeDefinition(scope.Value, typeName.Value)
	if typeDefinition == nil {
		return false
	}
	//获取第一个(位置
	index = strings.Index(funName, "(")
	if index == -1 {
		return false
	}
	//截取第一个(之前的字符串
	funName = funName[:index]
	_, p1 := typeDefinition.Methods[funName]
	if !p1 {
		return false
	}
	return true
}

// 判断是否开头是this.的属性调用
func IsThisProp(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断开头是否是this.
	if !strings.HasPrefix(codeLine, "this.") {
		return false
	}
	//获取当前实例地址
	currentInstanceAddress := threadStore.CurrentInstanceAddress
	if currentInstanceAddress == "" {
		return false
	}
	//获取地址对应的实例 ,判断此实例是否有此属性
	prop, _ := store.GetInstanceProp(threadStore, currentInstanceAddress)
	//获取第一个点位置
	index := strings.Index(codeLine, ".")
	//截取第一个.之后的字符串
	funName := codeLine[index+1:]
	_, p1 := prop[funName]
	if !p1 {
		return false
	}
	return true
}

// 判断是this.的属性赋值
func IsThisPropAssign(threadStore *structdef.ThreadStore, codeLine string) bool {
	//判断开头是否是this.
	if !strings.HasPrefix(codeLine, "this.") {
		return false
	}
	//获取第一个=的位置
	index1 := strings.Index(codeLine, "=")
	if index1 == -1 {
		return false
	}
	//获取当前实例地址
	currentInstanceAddress := threadStore.CurrentInstanceAddress
	if currentInstanceAddress == "" {
		return false
	}
	//获取地址对应的实例 ,判断此实例是否有此属性
	prop, _ := store.GetInstanceProp(threadStore, currentInstanceAddress)
	//获取第一个点位置
	index2 := strings.Index(codeLine, ".")
	//截取第一个.到=之间的字符串
	funName := codeLine[index2+1 : index1]
	_, p1 := prop[funName]
	if !p1 {
		return false
	}
	return true
}

// 判断是否是跨文件访问定义方法
func IsCrossFileDefineMethodCall(threadStore *structdef.ThreadStore, codeLine string) bool {
	//获取第一个点位置
	index := strings.Index(codeLine, ".")
	if index == -1 {
		return false
	}
	//截取第一个.之前的字符串,文件名
	fileName := codeLine[:index]
	handleFilePath := threadStore.HandleFilePath
	//获取fileName对应的映射路径
	filePath := store.GetImportFile(handleFilePath, fileName)
	if filePath == "" {
		return false
	}
	///截取fileName之后的字符串
	funName := codeLine[index+1:]
	//获取第一个(位置
	index1 := strings.Index(funName, "(")
	//截取第一个.到第一个(的字符
	funName = funName[:index1]
	//判断此作用域是否存在这个函数定义
	b := store.GetFunDefinition(filePath, funName)
	if b == nil {
		return false
	}
	return true
}

// 判断是否是实例变量调用方法
func IsInstanceMethodCall(threadStore *structdef.ThreadStore, codeLine string) bool {
	//获取第一个点位置
	index := strings.Index(codeLine, ".")
	if index == -1 {
		return false
	}
	//截取第一个.之前的字符串
	instanceName := codeLine[:index]
	addr, _, b := store.Get3LevelVariable(threadStore, instanceName)
	if !b {
		return false
	}
	//获取实例
	instance, b := store.GetInstanceProp(threadStore, addr.Value)
	if !b {
		return false
	}
	typeName, _ := instance["@TYPENAME@"]  //获取实例的类型名称
	scope, _ := instance["@TYPEFILEPATH@"] //获取实例的类型名称
	typeDefinition := store.GetTypeDefinition(scope.Value, typeName.Value)
	if typeDefinition == nil {
		return false
	}
	//截取第一个.之后的字符串
	funName := codeLine[index+1:]
	//截取第一个(位置
	index1 := strings.Index(funName, "(")
	if index1 == -1 {
		return false
	}
	//截取第一个.到第一个(的字符
	funName = funName[:index1]
	//判断是否是实例函数调用
	_, b = typeDefinition.Methods[funName]
	if !b {
		return false
	}
	return true
}

// 判断是否是实例调用属性
func IsInstanceProp(threadStore *structdef.ThreadStore, codeLine string) bool {
	//获取第一个点位置
	index := strings.Index(codeLine, ".")
	if index == -1 {
		return false
	}
	//截取第一个.之前的字符串
	instanceName := codeLine[:index]
	//判断是否是实例变量
	addr, b := store.GetInstance(threadStore, instanceName)
	if !b {
		return false
	}
	//截取第一个.之后的字符串
	propName := codeLine[index+1:]
	//判断此实例是否有此属性
	prop, b1 := store.GetInstanceProp(threadStore, addr)
	if !b1 {
		return false
	}
	_, b2 := prop[propName]
	if !b2 {
		panic("错误::::::实例" + instanceName + "中没有" + propName + "的成员变量定义")
	}
	if b2 {
		return true
	}
	return false
}

// 判断是否是类型属性
func IsInstanceAttribute(threadStore *structdef.ThreadStore, str string) bool {
	currentInstanceAddress := threadStore.CurrentInstanceAddress
	if currentInstanceAddress == "" {
		return false
	}
	prop, b := store.GetInstanceProp(threadStore, currentInstanceAddress)
	if b {
		_, b1 := prop[str]
		if b1 {
			return true
		}
	}
	//当前实例拿不到去获取父实例
	parentInstanceAddress := threadStore.ParentInstanceAddress
	if currentInstanceAddress == parentInstanceAddress {
		return false
	}
	prop, b = store.GetInstanceProp(threadStore, parentInstanceAddress)
	if b {
		_, b1 := prop[str]
		if b1 {
			return true
		}
	}
	return false
}

// 判断是类型属性赋值
func IsInstanceAttributeAssignment(threadStore *structdef.ThreadStore, str string) bool {
	currentInstanceAddress := threadStore.CurrentInstanceAddress
	if currentInstanceAddress == "" {
		return false
	}
	//截取第一个=之前的字符串
	index := strings.Index(str, "=")
	if index == -1 {
		return false
	}
	str = str[:index]
	prop, b := store.GetInstanceProp(threadStore, currentInstanceAddress)
	if b {
		_, b1 := prop[str]
		if b1 {
			return true
		}
	}
	return false
}

// 判断是否是函数调用传参,命名参数赋值$参数名=参数值
func IsFuncNameParameter(codeLine string) bool {
	//判断是否是函数调用传参,命名参数赋值$参数名=参数值
	if !strings.HasPrefix(codeLine, "$") {
		return false
	}
	//获取第一个=位置
	index := strings.Index(codeLine, "=")
	if index == -1 {
		return false
	}
	return true
}

// 判断是否是无限循环
func IsForInfiniteLoop(lineContent string) bool {
	//判断开头是否是for{
	if !strings.HasPrefix(lineContent, "for{") {
		return false
	}
	return true
}

// 判断是否是in循环,迭代器循环
func IsForInLoop(lineContent string) bool {
	//判断开头是否是for
	if !strings.HasPrefix(lineContent, "for") {
		return false
	}
	//判断结尾是否是{
	if !strings.HasSuffix(lineContent, "{") {
		return false
	}
	//判断是否包含in
	if !strings.Contains(lineContent, "->") {
		return false
	}
	return true
}

// 判断是否是数字迭代器循环
func IsForNumberLoop(lineContent string) bool {
	loop := IsForInLoop(lineContent)
	if !loop {
		return false
	}
	//判断是否包含..
	if !strings.Contains(lineContent, "..") {
		return false
	}
	return true
}

// 判断是否是for i循环
func IsForLoop(lineContent string) bool {
	//判断开头是否是for
	if !strings.HasPrefix(lineContent, "for") {
		return false
	}
	//判断结尾是否是{
	if !strings.HasSuffix(lineContent, "{") {
		return false
	}
	//判断是否存在2个分号
	if strings.Count(lineContent, ";") != 2 {
		return false
	}
	return true
}

// 判断是条件循环 for { }
func IsForConditionLoop(lineContent string) bool {
	//判断开头是否是for
	if !strings.HasPrefix(lineContent, "for") {
		return false
	}
	//判断结尾是否是{
	if !strings.HasSuffix(lineContent, "{") {
		return false
	}
	//判断是否包含in,如果包含in则不是条件循环
	if strings.Contains(lineContent, "->") {
		return false
	}
	//判断是否存在2个分号,如果存在那么就是 迭代循环
	if strings.Count(lineContent, ";") == 2 {
		return false
	}
	return true
}

// 判断是否是注解
func IsAnnotation(codeLine string) bool {
	//判断开头是否是@
	prefix := strings.HasPrefix(codeLine, "@")
	if !prefix {
		return false
	}
	//判断是否有(
	contains := strings.Contains(codeLine, "(")
	if !contains {
		return false
	}
	//判断括号是否成对
	if strings.Count(codeLine, "(") != strings.Count(codeLine, ")") {
		return false
	}
	return true
}

// 判断是实例属性赋值
func IsInstancePropAssignment(threadStore *structdef.ThreadStore, str string) bool {
	//获取第一个=位置
	index1 := strings.Index(str, "=")
	if index1 == -1 {
		return false
	}
	//获取第一个.位置
	index2 := strings.Index(str, ".")
	if index2 == -1 {
		return false
	}
	//获取第一个点之前的字符串
	instanceName := str[:index2]
	addr, b := store.GetInstance(threadStore, instanceName)
	if !b {
		return false
	}
	//截取第一个.到第一个=的字符
	propName := str[index2+1 : index1]
	prop, b := store.GetInstanceProp(threadStore, addr)
	if b {
		_, b1 := prop[propName]
		if b1 {
			return true
		}
	}
	return false
}

// 判断是否是连续调用 例如: a.b().c().d()
func IsUniteCallChain(threadStore *structdef.ThreadStore, codeLine string) bool {
	maps, str := utils.FuncBracketsReplace(codeLine)
	//判断如果有=号,则不是连续调用,而是赋值连续调用
	if strings.Contains(str, "=") {
		return false
	}

	//判断str.大于2个
	if strings.Contains(str, ".") && strings.Count(str, ".") >= 2 {
		return true
	}
	//可能是show().a这种情况
	//获取第一个.位置
	index := strings.Index(str, ".")
	if index == -1 {
		return false
	}
	//截取第一个.之前的字符串
	str = str[:index]
	//替换回去
	str = utils.FuncBracketsReplaceBack(maps, str)
	//判断是否是函数调用
	if IsMethodCall(threadStore, str) {
		return true
	}

	return false
}

// 判断是否是连续调用赋值语言
func IsUniteCallChainAssignment(threadStore *structdef.ThreadStore, codeLine string) bool {
	maps, str := utils.FuncBracketsReplace(codeLine)
	//获取第一个=位置
	index := strings.Index(str, "=")
	if index == -1 {
		return false
	}
	//判断str.大于2个
	if strings.Contains(str, ".") && strings.Count(str, ".") >= 2 {
		return true
	}
	//可能是show().a这种情况
	//获取第一个.位置
	index1 := strings.Index(str, ".")
	if index1 == -1 {
		return false
	}
	//截取第一个.之前的字符串
	str = str[:index1]
	//替换回去
	str = utils.FuncBracketsReplaceBack(maps, str)
	//判断是否是函数调用
	if IsMethodCall(threadStore, str) {
		return true
	}
	return false
}

// 判断是否是实例地址@#@
func IsInstanceAddress(str string) bool {
	if strings.HasPrefix(str, "@#@") && strings.HasSuffix(str, "@#@") {
		return true
	}
	return false
}

// 判断表达中是否存在函数调用
func IsCalculateFunctionCall(codeLine string) bool {
	//获取第一个(
	index := strings.Index(codeLine, "(")
	if index == -1 {
		return false
	}

	//判断(和)是否成对出现
	//判断(和)是否成对出现
	count := strings.Count(codeLine, "(")
	if count > 0 && count != strings.Count(codeLine, ")") {
		return false
	}
	replace, _ := utils.FuncExpressionReplace(codeLine)
	if len(replace) > 0 {
		return true
	}
	return false
}

// 判断变量是否是实例
func IsInstance(threadStore *structdef.ThreadStore, varName string) bool {
	addr, b := store.GetInstance(threadStore, varName) //获取实例地址
	if !b {
		return false
	}
	//拿到变量的地址,获取实例属性,判断是否是实例
	_, b = store.GetInstanceProp(threadStore, addr)
	if b {
		return true
	}
	return false
}

// 判断变量是否是全局实例
func IsGlobalInstance(threadStore *structdef.ThreadStore, varName string) bool {
	addr, b := store.GetGlobalInstance(threadStore, varName) //获取实例地址
	if !b {
		return false
	}
	//拿到变量的地址,获取实例属性,判断是否是实例
	_, b = store.GetInstanceProp(threadStore, addr)
	if b {
		return true
	}
	return false
}

// 判断是否是字符串
func IsString(str string) bool {
	if strings.HasPrefix(str, "\"") && strings.HasSuffix(str, "\"") {
		return true
	}
	return false
}

// 判断是否是数字或者小数
func IsNumber(str1 string) bool {
	var pd = false
	length := len(str1)
	for i := 0; i < length; i++ {
		var str = string(str1[i])
		if str == "0" || str == "1" || str == "2" || str == "3" || str == "4" || str == "5" || str == "6" || str == "7" || str == "8" || str == "9" {
			pd = true
			continue
		}
		//如果是小数
		if str == "." && IsNumber(str1[i+1:]) {
			pd = true
			break
		}
		//如果都不是那么就不是数字
		pd = false
		break
	}
	return pd
}

// 判断是否是数字或者字符串
func IsNumberOrString(str1 string) bool {
	return IsNumber(str1) || IsString(str1)
}

// 判断是否是数字或者布尔值true,false
func IsNumberOrBool(str1 string) bool {
	if str1 == "true" || str1 == "false" {
		return true
	}
	return IsNumber(str1)
}

// 判断是否是布尔值true,false
func IsBool(str1 string) bool {
	if str1 == "true" || str1 == "false" {
		return true
	}
	return false
}

// 判断是否是小数
func IsFloat(str1 string) bool {
	var pd = false
	//判断是否存在小数点
	if strings.Contains(str1, ".") {
		//如果存在小数点,那么就判断是否是数字
		if IsNumber(str1) {
			pd = true
		}
	}
	return pd
}

// 判断是否是整数
func IsInt(str1 string) bool {
	var pd = false
	//判断是否存在小数点
	if !strings.Contains(str1, ".") {
		//如果不存在小数点,那么就判断是否是数字
		if IsNumber(str1) {
			pd = true
		}
	}
	return pd
}

// 判断是否是26个字母和_,支持大小写
func IsLetter(str1 string) bool {
	//转换成小写
	str1 = strings.ToLower(str1)
	length := len(str1)
	var pd = false
	for i := 0; i < length; i++ {
		var str = string(str1[i])
		if str == "a" || str == "b" || str == "c" || str == "d" || str == "e" || str == "f" || str == "g" ||
			str == "h" || str == "i" || str == "j" || str == "k" || str == "l" || str == "m" || str == "n" ||
			str == "o" || str == "p" || str == "q" || str == "r" || str == "s" || str == "t" || str == "u" ||
			str == "v" || str == "w" || str == "x" || str == "y" || str == "z" || str == "_" {
			pd = true
		}
	}

	return pd
}

// 判断是否是This
func IsThis(codeLine string) bool {
	if codeLine == "this" {
		return true
	}
	return false
}

// 判断是否空"
func IsEmpty(str string) bool {
	if str == "" {
		return true
	}
	return false
}

// 判断是否threadId,获取当前线程id
func IsThreadId(str string) bool {
	return str == "threadId"
}

// 返回值v不是数字,不是bool,不是地址,不是JSON,则加上双引号
func AddDoubleQuotationMarks(v string) string {
	//返回值v不是数字,不是bool,不是地址,则加上双引号
	isString := IsString(v)
	number := IsNumber(v)
	isBool := IsBool(v)
	address := IsInstanceAddress(v)
	json := utils.IsValidJSON(v)
	if !isString && !number && !isBool && !address && !json {
		v = "\"" + v + "\""
	}
	return v
}

// 返回值v不是数字,不是bool,不是地址,则加上双引号
func AddDoubleQuotationMarks1(v string) string {
	//返回值v不是数字,不是bool,不是地址,则加上双引号
	isString := IsString(v)
	number := IsNumber(v)
	isBool := IsBool(v)
	address := IsInstanceAddress(v)
	if !isString && !number && !isBool && !address {
		v = "\"" + v + "\""
	}
	return v
}

// 判断值不是数字,不是bool则加上双引号
func AddDoubleQuotationMarks2(v string) string {
	//返回值v不是数字,不是bool,不是地址,则加上双引号
	isString := IsString(v)
	number := IsNumber(v)
	isBool := IsBool(v)
	if !isString && !number && !isBool {
		v = "\"" + v + "\""
	}
	return v
}
